/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.trandio.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.GregorianCalendar;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.logging.Logger;

import java.io.*;
import java.util.*;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 *
 * @author Administrador
 */
public class Utiles {

    private static final String[] UNIDADES = {"", "un ", "dos ", "tres ", "cuatro ", "cinco ", "seis ", "siete ", "ocho ", "nueve "};
    private static final String[] DECENAS = {"diez ", "once ", "doce ", "trece ", "catorce ", "quince ", "dieciseis ",
        "diecisiete ", "dieciocho ", "diecinueve", "veinte ", "treinta ", "cuarenta ",
        "cincuenta ", "sesenta ", "setenta ", "ochenta ", "noventa "};
    private static final String[] CENTENAS = {"", "ciento ", "doscientos ", "trecientos ", "cuatrocientos ", "quinientos ", "seiscientos ",
        "setecientos ", "ochocientos ", "novecientos "};
    public static final String FILE_SEPARATOR = System.getProperty("file.separator");

    public Utiles() {
    }

    private String mayusculizarPrimera(String c) {
        String resto = c.substring(1);
        char letra = c.charAt(0);
        letra = Character.toUpperCase(letra);
        return (Character.toString(letra) + resto);
    }

    public static String[] split(String original, String separator) {
        Vector nodes = new Vector();

        // Parse nodes into vector
        int index = original.indexOf(separator);
        while (index >= 0) {
            nodes.addElement(original.substring(0, index));
            original = original.substring(index + separator.length());
            index = original.indexOf(separator);
        }
        // Get the last node
        nodes.addElement(original);

        // Create splitted string array
        String[] result = new String[nodes.size()];
        if (nodes.size() > 0) {
            for (int loop = 0; loop < nodes.size(); loop++) {
                result[loop] = (String) nodes.elementAt(loop);
            }
        }
        return result;
    }

    public static java.util.Date convierteStringToDate(String stFecha, String stFormato) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(stFormato);
            java.util.Date fecha = sdf.parse(stFecha);
            return fecha;
        } catch (Exception e) {
            Logger.getLogger("convierteStringToDate -- Ha ocurrdo un error en la conversión de la fecha" + e);
            return null;
        }

    }

    public static String sumarDiasFecha(String v_fecha_desembolso, int dias) {


        //System.out.println("fecha_entra: "+v_fecha_desembolso+"---"+dias);


        SimpleDateFormat formatoDelTexto = new SimpleDateFormat("yyyy-MM-dd");
        java.util.Date date = null;
        java.util.Date fechaSumada = null;
        String salida = "";


        //String v_fecha_desembolso = fechasum.toString();        
        try {
            date = formatoDelTexto.parse(v_fecha_desembolso);
        } catch (ParseException ex) {
            Logger.getLogger(Utiles.class.getName()).log(Level.SEVERE, null, ex);
        }


        GregorianCalendar calendar = new GregorianCalendar();
        calendar.setGregorianChange(date);
        calendar.set(GregorianCalendar.DAY_OF_YEAR, calendar.get(GregorianCalendar.DAY_OF_YEAR) + dias);
        fechaSumada = calendar.getTime();
        salida = formatoDelTexto.format(fechaSumada);

        return salida;
    }

    public static java.util.Date sumarDiasFecha(java.util.Date dtFecha, int inDias) {

        Calendar cal = Calendar.getInstance();
        cal.setTime(dtFecha);
        cal.add(Calendar.DAY_OF_YEAR, inDias);
        return cal.getTime();
    }

    public static void unzip(String zipFile) throws ZipException,
            IOException {

        System.out.println(zipFile);;
        int BUFFER = 2048;
        File file = new File(zipFile);

        ZipFile zip = new ZipFile(file);
        String newPath = zipFile.substring(0, zipFile.length() - 4);

        new File(newPath).mkdir();
        Enumeration zipFileEntries = zip.entries();

        // Process each entry
        while (zipFileEntries.hasMoreElements()) {
            // grab a zip file entry
            ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();

            String currentEntry = entry.getName();

            File destFile = new File(newPath, currentEntry);
            destFile = new File(newPath, destFile.getName());
            File destinationParent = destFile.getParentFile();

            // create the parent directory structure if needed
            destinationParent.mkdirs();
            if (!entry.isDirectory()) {
                BufferedInputStream is = new BufferedInputStream(zip.getInputStream(entry));
                int currentByte;
                // establish buffer for writing file
                byte data[] = new byte[BUFFER];

                // write the current file to disk
                FileOutputStream fos = new FileOutputStream(destFile);
                BufferedOutputStream dest = new BufferedOutputStream(fos,
                        BUFFER);

                // read and write until last byte is encountered
                while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
                    dest.write(data, 0, currentByte);
                }
                dest.flush();
                dest.close();
                is.close();
            }
            if (currentEntry.endsWith("zip")) {
                // found a zip file, try to open
                unzip(destFile.getAbsolutePath());
            }
        }
    }

    public static int calcularEdad(String fecha) {
        String datetext = fecha;
        try {
            Calendar birth = new GregorianCalendar();
            Calendar today = new GregorianCalendar();
            int age = 0;
            int factor = 0;
            Date birthDate = new SimpleDateFormat("dd-MM-yyyy").parse(datetext);
            Date currentDate = new Date(); //current date
            birth.setTime(birthDate);
            today.setTime(currentDate);
            if (today.get(Calendar.MONTH) <= birth.get(Calendar.MONTH)) {
                if (today.get(Calendar.MONTH) == birth.get(Calendar.MONTH)) {
                    if (today.get(Calendar.DATE) > birth.get(Calendar.DATE)) {
                        factor = 0; //Aun no celebra su cumpleaÃ±os
                    }
                } else {
                    factor = 0; //Aun no celebra su cumpleaÃ±os
                }
            }
            age = (today.get(Calendar.YEAR) - birth.get(Calendar.YEAR)) + factor;
            return age;
        } catch (ParseException e) {
            return 0;
        }

    }

    public static String calcularEdad(int anio, int mes, int dia) {

        Calendar nacimiento = Calendar.getInstance();
        nacimiento.set(anio, mes - 1, dia, 0, 0);

        Calendar edad = Calendar.getInstance();

        edad.add(Calendar.MONTH, -nacimiento.get(Calendar.MONTH));
        edad.add(Calendar.DATE, -nacimiento.get(Calendar.DATE));
        edad.add(Calendar.YEAR, -nacimiento.get(Calendar.YEAR));


        String edadRes = "";


        // System.out.println(edad.get(Calendar.YEAR)+"años , "+edad.get(Calendar.MONTH)+" Meses , "+edad.get(Calendar.DATE)+" Dias");


        String anios = calcularEdad(dia + "-" + mes + "-" + anio) + "A";
        String meses = edad.get(Calendar.MONTH) + "M";
        String dias = edad.get(Calendar.DATE) + "D";


        if (anios.equals("0A")) {
            anios = "";
        }

        if (meses.equals("0M") || !anios.equals("")) {
            meses = "";
        }

        if (dias.equals("0D") || !meses.equals("") || !anios.equals("")) {
            dias = "";
        }


        edadRes = anios + meses + dias;


        return edadRes;

    }

    public static String getDiaDeSemana(Date d) {
        String nombreDia = "";
        GregorianCalendar cal = new GregorianCalendar();
        cal.setTime(d);

        switch (cal.get(Calendar.DAY_OF_WEEK)) {
            case 1:
                nombreDia = "Domingo";
                break;
            case 2:
                nombreDia = "Lunes";
                break;
            case 3: {
                nombreDia = "Martes";
            }
            break;
            case 4: {
                nombreDia = "Miercoles";
            }
            break;
            case 5: {
                nombreDia = "Jueves";
            }
            break;
            case 6: {
                nombreDia = "Viernes";
            }
            break;
            case 7: {
                nombreDia = "Sábado";
            }
            break;


        }
        return nombreDia;
    }

    public static void getAllFiles(File dir, List<File> fileList) {
        try {
            File[] files = dir.listFiles();
            for (File file : files) {
                fileList.add(file);
                if (file.isDirectory()) {
                    System.out.println("directory:" + file.getCanonicalPath());
                    getAllFiles(file, fileList);
                } else {
                    System.out.println("     file:" + file.getCanonicalPath());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void writeZipFile(File directoryToZip, List<File> fileList) {

        try {
            //FileOutputStream fos = new FileOutputStream(directoryToZip.getName() + ".zip");
            FileOutputStream fos = new FileOutputStream(directoryToZip.getCanonicalPath() + ".zip");

            ZipOutputStream zos = new ZipOutputStream(fos);

            for (File file : fileList) {
                if (!file.isDirectory()) { // we only zip files, not directories
                    addToZip(directoryToZip, file, zos);
                }
            }

            zos.close();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void addToZip(File directoryToZip, File file, ZipOutputStream zos) throws FileNotFoundException, IOException {
        FileInputStream fis = new FileInputStream(file);
        // we want the zipEntry's path to be a relative path that is relative
        // to the directory being zipped, so chop off the rest of the path
        String zipFilePath = file.getCanonicalPath().substring(directoryToZip.getCanonicalPath().length() + 1,
                file.getCanonicalPath().length());

        System.out.println("Writing '" + zipFilePath + "' to zip file");
        ZipEntry zipEntry = new ZipEntry(zipFilePath);
        zos.putNextEntry(zipEntry);

        byte[] bytes = new byte[2048];
        int length;

        while ((length = fis.read(bytes)) > 0) {
            zos.write(bytes, 0, length);
        }
        zos.closeEntry();
        fis.close();

    }

    public static  String convertirNumeroLetra(String numero, boolean mayusculas) {
        String literal = "";
        String parte_decimal;
        //si el numero utiliza (.) en lugar de (,) -> se reemplaza
        numero = numero.replace(".", ",");
        //si el numero no tiene parte decimal, se le agrega ,00
        if (numero.indexOf(",") == -1) {
            numero = numero + ",00";
        }
        //se valida formato de entrada -> 0,00 y 999 999 999,00
        if (Pattern.matches("\\d{1,9},\\d{1,2}", numero)) {
            //se divide el numero 0000000,00 -> entero y decimal
            String Num[] = numero.split(",");
            //de da formato al numero decimal
            parte_decimal = Num[1] + "/100 Pesos.";
            //se convierte el numero a literal
            if (Integer.parseInt(Num[0]) == 0) {//si el valor es cero
                literal = "cero ";
            } else if (Integer.parseInt(Num[0]) > 999999) {//si es millon
                literal = getMillones(Num[0]);
            } else if (Integer.parseInt(Num[0]) > 999) {//si es miles
                literal = getMiles(Num[0]);
            } else if (Integer.parseInt(Num[0]) > 99) {//si es centena
                literal = getCentenas(Num[0]);
            } else if (Integer.parseInt(Num[0]) > 9) {//si es decena
                literal = getDecenas(Num[0]);
            } else {//sino unidades -> 9
                literal = getUnidades(Num[0]);
            }
            //devuelve el resultado en mayusculas o minusculas
            if (mayusculas) {
                return (literal + parte_decimal).toUpperCase();
            } else {
                return (literal + parte_decimal);
            }
        } else {//error, no se puede convertir
            return literal = null;
        }
        
        
        
        
    }

    /*
     * funciones para convertir los numeros a literales
     */
    public static String getUnidades(String numero) {// 1 - 9
        //si tuviera algun 0 antes se lo quita -> 09 = 9 o 009=9
        String num = numero.substring(numero.length() - 1);
        return UNIDADES[Integer.parseInt(num)];
    }

    public static String getDecenas(String num) {// 99                        
        int n = Integer.parseInt(num);
        if (n < 10) {//para casos como -> 01 - 09
            return getUnidades(num);
        } else if (n > 19) {//para 20...99
            String u = getUnidades(num);
            if (u.equals("")) { //para 20,30,40,50,60,70,80,90
                return DECENAS[Integer.parseInt(num.substring(0, 1)) + 8];
            } else {
                return DECENAS[Integer.parseInt(num.substring(0, 1)) + 8] + "y " + u;
            }
        } else {//numeros entre 11 y 19
            return DECENAS[n - 10];
        }
    }

    public static String getCentenas(String num) {// 999 o 099
        if (Integer.parseInt(num) > 99) {//es centena
            if (Integer.parseInt(num) == 100) {//caso especial
                return " cien ";
            } else {
                return CENTENAS[Integer.parseInt(num.substring(0, 1))] + getDecenas(num.substring(1));
            }
        } else {//por Ej. 099 
            //se quita el 0 antes de convertir a decenas
            return getDecenas(Integer.parseInt(num) + "");
        }
    }

    public static String getMiles(String numero) {// 999 999
        //obtiene las centenas
        String c = numero.substring(numero.length() - 3);
        //obtiene los miles
        String m = numero.substring(0, numero.length() - 3);
        String n = "";
        //se comprueba que miles tenga valor entero
        if (Integer.parseInt(m) > 0) {
            n = getCentenas(m);
            return n + "mil " + getCentenas(c);
        } else {
            return "" + getCentenas(c);
        }

    }

    public static String getMillones(String numero) { //000 000 000        
        //se obtiene los miles
        String miles = numero.substring(numero.length() - 6);
        //se obtiene los millones
        String millon = numero.substring(0, numero.length() - 6);
        String n = "";
        if (millon.length() > 1) {
            n = getCentenas(millon) + "millones ";
        } else {
            n = getUnidades(millon) + "millon ";
        }
        return n + getMiles(miles);
    }
}
